package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.heima.apis.ariticle.IArticleClient;
import com.heima.apis.schedule.IScheduleClient;
import com.heima.audit.aliyun.GreenImageScan;
import com.heima.audit.aliyun.GreenTextScan;
import com.heima.audit.tess4j.Tess4jClient;
import com.heima.common.constants.WemediaConstants;
import com.heima.common.redis.CacheService;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.service.*;
import net.sourceforge.tess4j.TesseractException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

@Service
public class WmNewsAutoServiceImpl implements WmNewsAutoService {
    @Autowired
    private WmNewsService wmNewsService;
    @Autowired
    private WmMaterialService wmMaterialService;
    @Autowired
    private WmNewsMaterialService wmNewsMaterialService;
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private FileStorageService fileStorageService;
    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private ExecutorService executorService;
    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private Tess4jClient tess4jClient;
    @Autowired
    private WmUserService wmUserService;
    @Autowired
    private WmChannelService wmChannelService;
    @Autowired
    private KafkaTemplate kafkaTemplate;
    @Autowired
    private IScheduleClient iScheduleClient;




    @Override
    @Async
    public void disposeNews(WmNews wmNews){
        if (auditNews(wmNews)) {
            sendToApp(wmNews);
    }
    }




    /**
     * 审核用户上传的内容
     */
    public  boolean auditNews(WmNews wmNews){
        List<String> textAllList = new ArrayList();
        Set<String> imagesAllSet = new HashSet();

        textAllList.add(wmNews.getTitle());
        String content = wmNews.getContent();
        JSONArray contentList = JSON.parseArray(content);
        for (Object o : contentList) {
            Map map= (Map) o;
            String type = (String) map.get("type");
            if ("image".equals(type)){
                //获取Content中的文件连接
                imagesAllSet.add((String) map.get("value"));
            }else {
                if (!map.containsValue("请在这里输入正文")) {
                    //获取所有内容的文本数据
                    textAllList.add(map.get("value").toString());
                }
            }
        }
        String images = wmNews.getImages();
        if (images!=null){
            String[] imageArray = images.split(",");
            for (String image : imageArray) {
                imagesAllSet.add(image);
            }
        }
        try {
            //先去图片去提取文字
            //根据imageUrl去下载图片
            List<byte[]> imageList = null;
            if (!imagesAllSet.isEmpty()){
                imageList = imagesAllSet.stream().map(imageUrl -> {
                    byte[] bytes = fileStorageService.downLoadFile(imageUrl);
                    return bytes;
                }).collect(Collectors.toList());
                for (byte[] bytes : imageList) {
                    //根据谷歌算法去提取文字
                    String picText = getPicText(bytes);
                    //将图片文本与之前集合合并
                    textAllList.add(picText);
                }
            }
            //字符串集合转字符串
            String allText=String.join("",textAllList);
            //先去本地敏感词审查
            if (!auditTextByLocal(wmNews,allText)){
                //没通过
                return false;
            }
            //阿里审核
/*         //如果验证全部通过就进行阿里验证
            if (!auditTextByAli(wmNews,allText)){
                //没通过
                return false;
            }
            if (!imageList.isEmpty()&&!auditImageByAli(wmNews,imageList)){
                //如果为空就不会进第二个方法
                //没过
                return false;
            }*/

        } catch (Exception e) {
            e.printStackTrace();
            updateStatus(wmNews, WmNews.Status.FAIL, "审核失败");
            return false;
        }
        //审核通过
        updateStatus(wmNews,WmNews.Status.SUCCESS, "审核通过");

        return true;

    }
    /**
     * 图片获取文本
     */
    private String getPicText(byte[] bytes) throws IOException, TesseractException {
        ByteArrayInputStream in = new ByteArrayInputStream(bytes);
        BufferedImage imageFile = ImageIO.read(in);
        String result = tess4jClient.doOCR(imageFile);
        return  result;
    }

    /**
     * 本地验证敏感词
     */
    private boolean auditTextByLocal(WmNews wmNews,String allText){

        Set<String> wmSensitiveset = cacheService.scan(WemediaConstants.CATCH_KEY_SENSITIVE);
        if (wmSensitiveset.isEmpty()){
            List<WmSensitive> wmSensitiveList = wmSensitiveMapper.selectList(null);
            List<String> sensitivesList = wmSensitiveList.stream().map(wmSensitive -> {
                String sensitives = wmSensitive.getSensitives();
                return sensitives;
            }).collect(Collectors.toList());
            String[] sensitives =new String[sensitivesList.size()];

            for (int i = 0; i < sensitives.length; i++) {
                sensitives[i] = sensitivesList.get(i);
            }
            cacheService.sAdd(WemediaConstants.CATCH_KEY_SENSITIVE,sensitives);
            wmSensitiveset.addAll(sensitivesList);
        }
        SensitiveWordUtil.initMap(wmSensitiveset);
        Map<String, Integer> stringIntegerMap = SensitiveWordUtil.matchWords(allText);
        if (!stringIntegerMap.isEmpty()){
            updateStatus(wmNews, WmNews.Status.FAIL, "审核失败");
            return false;
        }
        return true;
    }

    /**
     * 从阿里去审核图片
     */
    private boolean auditImageByAli(WmNews wmNews, List<byte[]> imageList) throws Exception {
        Map inagesResultMap = greenImageScan.imageScan(imageList);
        String inagesSuggestion = (String) inagesResultMap.get("suggestion");
        if(inagesSuggestion.equals("review")){
            wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode().shortValue());
            wmNews.setReason("人工审核");
            return false;
        }else if (inagesSuggestion.equals("block")){
            wmNews.setStatus(WmNews.Status.FAIL.getCode().shortValue());
            wmNews.setReason("审核失败");
            return false;
        }
        return true;
    }

    /**
     * 去阿里云审核文本
     */
    private boolean auditTextByAli(WmNews wmNews, String textAll) throws Exception {
        Map textResultMap = greenTextScan.greeTextScan(textAll);
        String suggestion = (String) textResultMap.get("suggestion");
        if(suggestion.equals("review")){
            updateStatus(wmNews, WmNews.Status.ADMIN_AUTH, "人工审核");
            return false;
        }else if (suggestion.equals("block")){
            updateStatus(wmNews, WmNews.Status.FAIL, "审核失败");
            return false;
        }
        return true;
    }

    /**
     * 更新news的状态
     */
    private void updateStatus(WmNews wmNews, WmNews.Status fail, String reason) {
        wmNews.setStatus(fail.getCode().shortValue());
        wmNews.setReason(reason);
        wmNewsService.updateById(wmNews);
    }
    private void sendToApp(WmNews wmNews) {
        //审核通过就讲存入文章服务
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setContent(wmNews.getContent());
        articleDto.setAuthorId(Long.valueOf(wmNews.getUserId()));
        articleDto.setLayout(Short.valueOf(""+wmNews.getType()));
        WmUser user= wmUserService.getById(wmNews.getUserId());
        articleDto.setAuthorName(user.getName());
        Thread thread = new Thread();
        thread.start();

        WmChannel channel = wmChannelService.getById(wmNews.getChannelId());
        articleDto.setChannelName(channel.getName());
        ResponseResult responseResult = iArticleClient.save(articleDto);
        if(responseResult.getCode()== AppHttpCodeEnum.SUCCESS.getCode()){
            updateStatus(wmNews, WmNews.Status.PUBLISHED, "发送成功");
            //返回的id存入对应的文章id中
            wmNews.setArticleId((Long) responseResult.getData());
            wmNewsService.updateById(wmNews);

        }else{
            updateStatus(wmNews, WmNews.Status.ADMIN_AUTH, "转人工");
        }
    }

}
